﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
using X.Infrastructure.Shapes;
using X.Infrastructure.WPF.Caliburn.AdviceAttributes;
using X.Infrastructure.WPF.Caliburn.Base;
using X.WPF.Controls.EventArgs.CanvasShapeArgs;
using X.WPF.Controls.Sample.Models;
using X.WPF.Controls.Sample.Views.ImageContext;

namespace X.WPF.Controls.Sample.ViewModels.ImageContext
{
    /// <summary>
    /// 图片画布 视图模型
    /// </summary>
    public class ImageCanvasViewModel : ScreenBase
    {

        #region # 字段及构造器

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public ImageCanvasViewModel()
        {
            this.Areas = new ObservableCollection<Wrap<ImageAreaNm>>();
            this.AreaShapes = new ObservableCollection<ShapeX>();
        }

        #endregion

        #region # 属性 

        #region 图片路径 —— string ImagePath
        /// <summary>
        /// 图片路径
        /// </summary>
        [DependencyProperty]
        public string ImagePath { get; set; }
        #endregion

        #region 图片区域形状列表 —— ObservableCollection<ShapeX> AreaShapes
        /// <summary>
        /// 图片区域形状列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<ShapeX> AreaShapes { get; set; }
        #endregion

        #region 选中的图片区域形状 —— ShapeX SelectedAreaShape
        /// <summary>
        /// 选中的图片区域形状
        /// </summary>
        [DependencyProperty]
        public ShapeX SelectedAreaShape { get; set; }
        #endregion

        #region 图片区域列表 —— ObservableCollection<Wrap<ImageAreaNm>> Areas
        /// <summary>
        /// 图片区域列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<Wrap<ImageAreaNm>> Areas { get; set; }
        #endregion

        #region 选中的图片区域 —— Wrap<ImageAreaNm> SelectedArea
        /// <summary>
        /// 选中的图片区域
        /// </summary>
        [DependencyProperty]
        public Wrap<ImageAreaNm> SelectedArea { get; set; }
        #endregion

        #region 形状右键菜单 —— ContextMenu ShapeContextMenu
        /// <summary>
        /// 形状右键菜单
        /// </summary>
        [DependencyProperty]
        public ContextMenu ShapeContextMenu { get; set; }
        #endregion

        #endregion

        #region # 方法

        //Initializations

        #region 初始化 —— Task OnInitializeAsync(CancellationToken cancellationToken)
        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        protected override Task OnInitializeAsync(CancellationToken cancellationToken)
        {
            ImageCanvasView view = (ImageCanvasView)this.GetView();
            this.ShapeContextMenu = (ContextMenu)view.Resources["ShapeContextMenu"];



            return base.OnInitializeAsync(cancellationToken);
        }
        #endregion

        #region 加载 —— void Load()
        /// <summary>
        /// 加载
        /// </summary>
        public void Load()
        {
            this.ReloadAreas();

            this.ImagePath = @"E:\\__Bgi\\86.jpg";
        }
        #endregion 


        //Actions

        #region 加载图片 —— void LoadImage()
        /// <summary>
        /// 加载图片
        /// </summary>
        public void LoadImage()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Filter = "图像文件(*.bmp,*.png,*.jpg)|*.bmp;*.png;*.jpg",
                AddExtension = true,
                RestoreDirectory = true
            };

            if (openFileDialog.ShowDialog() != true)
                return;

            this.Busy();

            // 上传图片
            this.ImagePath = openFileDialog.FileName;

            this.Idle();
        }
        #endregion

        #region 查看原始图片 —— async void LookOriginalImage()
        /// <summary>
        /// 查看原始图片
        /// </summary>
        public async void LookOriginalImage()
        {

            //if (string.IsNullOrWhiteSpace(this.ImagePath))
            //{
            //    MessageBox.Show("请选择图片！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            //    return;
            //}

            //this.Busy();

            //ImageViewModel viewModel = ResolveMediator.Resolve<ImageViewModel>();

            //// TODO 填充图形
            ////viewModel.Load(this.ImagePath, this.ImageRectangles);

            //this.Idle();

            //await this._windowManager.ShowDialogAsync(viewModel);
        }
        #endregion

        #region 创建图片区域 —— void CreateImageArea(CanvasShapeDrawnEventArgs eventArgs)
        /// <summary>
        /// 创建图片区域
        /// </summary>
        public async void CreateImageArea(CanvasShapeDrawnEventArgs eventArgs)
        {
            //AddImageAreaViewModel viewModel = ResolveMediator.Resolve<AddImageAreaViewModel>();

            //bool? result = await this._windowManager.ShowDialogAsync(viewModel);

            //if (result == null || !result.Value)
            //{
            //    eventArgs.IsCancel = true;
            //    return;
            //}

            ImageAreaNm area = new ImageAreaNm
            {
                Number = Guid.NewGuid().ToString(),
                Location = eventArgs.Shape
            };
            eventArgs.Shape.Tag = area;

            List<Wrap<ImageAreaNm>> imageAreaNms = this.Areas.ToList();
            imageAreaNms.Add(area.Wrap());
            this.Areas = new ObservableCollection<Wrap<ImageAreaNm>>(imageAreaNms);

        }
        #endregion

        #region 修改图片区域 —— void UpdateImageArea(Wrap<ImageAreaNm>? wrap)
        /// <summary>
        /// 修改图片区域
        /// </summary>
        /// <param name="wrap">图片区域</param>
        public async void UpdateImageArea(Wrap<ImageAreaNm>? wrap)
        {
            ImageAreaNm imageArea = wrap == null ? (ImageAreaNm)this.SelectedAreaShape?.Tag! : wrap.Model;

            MessageBox.Show(imageArea.Number);
        }
        #endregion

        #region 删除图片区域 —— void RemoveImageArea(Wrap<ImageAreaNm>? wrap)
        /// <summary>
        /// 删除图片区域
        /// </summary> 
        /// <param name="wrap">图片区域</param>
        public async void RemoveImageArea(Wrap<ImageAreaNm>? wrap)
        {
            this.Busy();

            if (wrap == null && this.SelectedAreaShape?.Tag == null)
                return;

            wrap ??= this.Areas.Single(i => i.Model == (ImageAreaNm)this.SelectedAreaShape?.Tag!);

            // 删除图像上的矩形
            ShapeX[] shapes = this.AreaShapes.Where(x => ((ImageAreaNm)x.Tag).Number == wrap.Model.Number).ToArray();
            foreach (ShapeX shape in shapes)
            {
                this.AreaShapes.Remove(shape);
            }

            // 删除图片项
            this.Areas.Remove(wrap);

            // 清除选中
            this.SelectedAreaShape = null;

            this.Idle();
        }
        #endregion

        #region 图片区域选择变更 —— void SelectedAreaChange(Wrap<ImageAreaNm> wrap, SelectionChangedEventArgs e)
        /// <summary>
        /// 图片区域选择变更
        /// </summary>
        public void SelectedAreaChange(Wrap<ImageAreaNm> wrap, SelectionChangedEventArgs e)
        {
            if (wrap == null)
                return;

            ShapeX canvasShape = this.AreaShapes.SingleOrDefault(i => i.Name == this.SelectedArea.Model.Location.Name);

            this.SelectedAreaShape = canvasShape;

            e.Handled = true;
        }
        #endregion

        #region 图片区域型状点击 —— async void AreaShapeClick(CanvasShapeClickEventArgs eventArgs)
        /// <summary>
        /// 图片区域型状点击
        /// </summary>
        /// <param name="eventArgs">型状点击事件参数</param>
        public async void AreaShapeClick(CanvasShapeClickEventArgs eventArgs)
        {
            ImageAreaNm wrapItem = (ImageAreaNm)eventArgs.Shape?.Tag;

            eventArgs.Handled = true;
        }
        #endregion

        #region 图片区域形状选择改变 —— void SelectedAreaShapeChanged(SelectedCanvasShapeChangedEventArgs eventArgs)
        /// <summary>
        /// 图片区域形状选择改变
        /// </summary>
        /// <param name="eventArgs">矩形点击事件参数</param>
        public void SelectedAreaShapeChanged(SelectedCanvasShapeChangedEventArgs eventArgs)
        {
            ImageAreaNm wrapItem = (ImageAreaNm)eventArgs.Shape?.Tag;

            if (wrapItem == null)
            {
                foreach (Wrap<ImageAreaNm> unselectedItem in this.Areas)
                {
                    unselectedItem.IsSelected = false;
                }
            }
            else
            {
                Wrap<ImageAreaNm> selectedItem = this.Areas.Single(x => x.Model.Number == wrapItem.Number);
                IEnumerable<Wrap<ImageAreaNm>> unselectedItems = this.Areas.Where(x => x.Model.Number != wrapItem.Number);

                foreach (Wrap<ImageAreaNm> unselectedItem in unselectedItems)
                {
                    unselectedItem.IsSelected = false;
                }
                selectedItem.IsSelected = true;
            }

            eventArgs.Handled = true;
        }
        #endregion

        #region 图片区域形状拖拽改变 —— void AreaShapeDragChanging(CanvasShapeDragChangingEventArgs eventArgs)
        /// <summary>
        /// 图片区域形状拖拽改变
        /// </summary>
        /// <param name="eventArgs">图片区域形状拖拽改变事件参数</param>
        public void AreaShapeDragChanging(CanvasShapeDragChangingEventArgs eventArgs)
        {
            ImageAreaNm imageAreaNm = (ImageAreaNm)eventArgs.Shape.Tag;
            Wrap<ImageAreaNm> rectangle = this.Areas.Single(i => i.Model.Number == imageAreaNm.Number);
            rectangle.Model.Location = eventArgs.Shape;

            eventArgs.Handled = true;
        }
        #endregion

        #region 图片区域形状拖拽完成 —— void AreaShapeDragCompleted(CanvasShapeDragCompletedEventArgs eventArgs)
        /// <summary>
        /// 图片区域形状拖拽完成
        /// </summary>
        /// <param name="eventArgs">图片区域形状拖拽完成事件参数</param>
        public void AreaShapeDragCompleted(CanvasShapeDragCompletedEventArgs eventArgs)
        {
            ImageAreaNm imageAreaNm = (ImageAreaNm)eventArgs.Shape.Tag;
            Wrap<ImageAreaNm> rectangle = this.Areas.Single(i => i.Model.Number == imageAreaNm.Number);
            rectangle.Model.Location = eventArgs.Shape;

            eventArgs.Handled = true;
        }
        #endregion


        //Private

        #region 重新加载图片区域列表 —— void ReloadAreas()
        /// <summary>
        /// 重新加载图片区域列表
        /// </summary>
        private void ReloadAreas()
        {
            if (this.Areas.Any())
            {
                // 设置图片画布形状
                List<ShapeX> shapes = new List<ShapeX>();
                foreach (Wrap<ImageAreaNm> area in this.Areas)
                {
                    area.Model.Location.Tag = area.Model;
                    shapes.Add(area.Model.Location);
                }

                this.AreaShapes = new ObservableCollection<ShapeX>(shapes);
            }
            else
            {
                this.AreaShapes = new ObservableCollection<ShapeX>();
            }
        }
        #endregion

        #endregion

    }
}
